package com.cskaoyan.config;

import com.cskaoyan.bean.MallLog;
import com.cskaoyan.model.vo.BaseRespVo;
import com.cskaoyan.service.system.LogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @program: project-market
 * @description: 操作日志
 * @author: Weiwei Liu
 * @create: 2021-11-30 21:55
 **/
@Aspect  // 指定切入组件
@Component
public class OperationLogAspect {

    @Autowired
    LogService logService;

    MallLog mallLog = new MallLog();

    //使用@Pointcut的value属性作为切入点的表达式
    @Pointcut("execution(* com.cskaoyan.controller..*(..))")
    public void servicePointcut() { //方法名是作为id进行使用的
    }

    //通知注解的value属性；
    //   1、直接写切入点表达式
    //   2、引用切入点方法 👉 有一对括号
//    @Before("servicePointcut()")
//    public void beforeTarget() {
//        System.out.println("委托类方法执行之前");
//    }
//
//    @After("servicePointcut()")
//    public void after() {
//        System.out.println("在委托类方法执行之后");
//    }

    @Around("servicePointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        String action;

        //委托类对象，也就是Controller对象
        Object target = joinPoint.getTarget();

        mallLog.setAddTime(new Date());

        action = target.getClass().getSimpleName();

        action = action.replace("Controller", "");


        //之前拿到的是Method
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        String name = signature.getName();
        Method method = signature.getMethod();

        mallLog.setAction(action + "-" + method.getName());


        Object proceed = joinPoint.proceed();
        return proceed;
    }

    @AfterReturning(value = "servicePointcut()", returning = "result")
    public void afterReturning(Object result) {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String ip = request.getRemoteAddr();
        mallLog.setIp(ip);
        HttpSession session = request.getSession();
        if (session == null || session.getAttribute("username") == null) {
            mallLog.setAdmin("未知用户");
        } else {
            mallLog.setAdmin((String) session.getAttribute("username"));
        }


        mallLog.setUpdateTime(new Date());

        if (!(result instanceof BaseRespVo)) return;

        BaseRespVo vo = (BaseRespVo) result;

        if (0 == vo.getErrno()) {
            // 对应status为TRUE
            mallLog.setStatus(true);
        } else {
            // 对应status为False
            mallLog.setStatus(false);
        }


        mallLog.setResult(vo.getErrmsg());
        mallLog.setDeleted(false);
        mallLog.setType(1);

        logService.create(mallLog);
    }
//
//    //可以使用Exception或Throwable
//    @AfterThrowing(value = "servicePointcut()",throwing = "exception")
//    public void afterThrowing(Exception exception) {
//        System.out.println("AfterThrowing通知：" + exception.getMessage());
//    }
}
